#include "read_options.h"
namespace po = boost::program_options;
using std::vector;
using std::string;

#include <stdexcept>
	using std::runtime_error;
#include <boost/format.hpp>
		using boost::format;
#include <boost/assign/list_of.hpp> // for 'list_of()'
		using namespace boost::assign; // bring 'list_of()' into scope


//!_______________________________________________________________________________________
//!     
//!		operation_string_to_operation
//!			Convert command line operation string option to the correct operation (enum)
//!     
//!		\author lg (1/24/2011)
//!     
//!     \return eOPERATIONS 
//!_______________________________________________________________________________________

eOPERATIONS operation_string_to_operation(const string& operation)
{
	// check which operation is specified
	std::vector<string> operation_option_strings = list_of	("none")("expand")("bracket")
															("summarise")("join_neighbours")
															("remove_short")("union")("intersect")
															("difference");
	for (unsigned ii = 0; ii < operation_option_strings.size(); ++ii)
		if (operation == operation_option_strings[ii].substr(0, operation.length()))
			return eOPERATIONS(ii);

	throw std::runtime_error("--operation " + operation + " is not a recognised or valid choice.");
}

bool read_options(prog_options& opt, int argc, char *argv[])
{

	string operation;
	opt.mandatory.add_options()
								("input1_file,i",po::value<std::string>(&opt.input_file_name)
										//->set_name("FILE"),
										,"Intervals in tab delimited format <contig><beg><end>. "
										 "Can be a file glob (e.g. '*.nc').")
								("operation,X",po::value<string >(&operation)
										//->set_name("FILE"),
										,"The operation to be performed on the interval. "
										 "Can be 'expand', 'bracket', 'summarise', 'union', 'intersect', "
										 "'difference', 'join_neighbours', 'remove_short' or 'none'. ");

	opt.optional.add_options()
								("output_file,o",po::value<std::string>(&opt.output_file_name)
										//->set_name("FILE"),
                                        ,"Output. Can include format strings including:\n"
                                        "[FILENAME] = filename not including extension\n"
                                        "[EXT]      = extension including dot\n"
                                        "[PATH]     = path including final slash\n"
										"[NAME]     = \tinterval set name. Defaults to [FILENAME]. Can be set using "
										"--name_regex and --name_substitution_pattern")
								("input2_file,j",po::value<std::string>(&opt.input_file_name2)
										//->set_name("FILE"),
										,"Intervals in tab delimited format <contig><beg><end>. "
										 "Can include format strings. See above.")
								("regex,R",po::value<std::string>(&opt.name_regex)
										,"Regular expression specifying how the interval set name [NAME] is "
										 "constructed from the file name. Defaults to [FILENAME].")
								("name,N",po::value<std::string>(&opt.name_sub)
										,"Name of the interval set [NAME].\n"
										 "Can also be used in conjuction with --regex to "
										 "construct [NAME] from the file name using regular "
										 "expression substitution: Numeric backreferences "
										 "(\\1, \\2) are replaced by the contents of the "
										 "corresponding group.")
								("offset,O",po::value<unsigned >(&opt.offset)
										//->set_name("FILE"),
										->default_value(0U)
										,"How much to expand, or contract by or the limit for "
										 "joining neighbours or removing short intervals.")
								("zero_based_input,z",po::value<bool>(&opt.zero_based_input)
										->zero_tokens()
										,"Input interval files specified in zero based [) "
										 "coordinates (UCSC) rather than 1-based [] (Ensembl).")
								("zero_based_input2,Z",po::value<bool>(&opt.zero_based_input2)
										->zero_tokens()
										,"Second input interval files specified in zero "
										 "based coordinates.")
								("zero_based_output,Y",po::value<bool>(&opt.zero_based_output)
										->zero_tokens()
										,"Output interval files specified in zero based coordinates.")
								("contig_sizes_file,C",po::value<string>(&opt.contig_sizes_file_name)
										//->set_name("FILE"),
										,"For calculating percentages in summary information.\n"
		    							 "Tab delimited format <contig><beg><end>.\n"
										 "Assumes zero based [) coordinates (UCSC) ");
								


	
	opt.config_file.add_options()
								("input1_file,i",po::value<std::string>(&opt.input_file_name))
								("operation,X",po::value<string >(&operation))
								("output_file,o",po::value<std::string>(&opt.output_file_name))
								("input2_file,j",po::value<std::string>(&opt.input_file_name2))
								("regex,R",po::value<std::string>(&opt.name_regex))
								("name,N",po::value<std::string>(&opt.name_sub))
								("offset,O",po::value<unsigned >(&opt.offset))
								("zero_based_input",po::value<bool>(&opt.zero_based_input)
										->zero_tokens())
								("zero_based_input2",po::value<bool>(&opt.zero_based_input2)
										->zero_tokens())
								("zero_based_output",po::value<bool>(&opt.zero_based_output)
										->zero_tokens())
								("contig_sizes_file,C",po::value<string>(&opt.contig_sizes_file_name));
								


	if (!opt.process_command_line(argc, argv))
		return false;

	opt.operation = operation_string_to_operation(operation);
	if (opt.operation >= eUNION)
	{
		if (opt.input_file_name2.length() == 0)
			throw std::runtime_error("Two interval sets required. Please specify using --input_file_name2.");
	}


	return true;
}



